//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "DMDMain.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TmyForm *myForm;
//---------------------------------------------------------------------------
__fastcall TmyForm::TmyForm(TComponent* Owner)
  : TForm(Owner)
{
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::OpenBinaryTextData1Click(TObject *Sender)
{
  char buf[256],
       *p;
  LONG valu,
       cmpv;
  LONG cIndex;
  WORD pointer;
  FILE *tf;

  LONG offset;
  LONG lpPosi;
  int  count;

  Open1->Title      = "Open ROM File";
  Open1->Filter     = "NES ROM | *.nes";
  Open1->InitialDir = cur_dir;
  //
  if ( Open1->Execute( ) )
  { // Create Dump directory!
    getcwd( dirc, MAXPATH );
    strcat( dirc, "\\Dumps" );
    mkdir( dirc );

    //
    strcpy(romf, Open1->FileName.c_str( ) );
    tf = fopen( romf, "rb" );
    if ( !tf ){
      ShowMessage("Fatal Error: Could not open file!");
      return;
    }
    //
    _free( rom.data );
    rom.data = (BYTE *)malloc( rom.Length = FileSize( tf ) );
    //
    if ( !rom.data ){
      fclose( tf );
      ShowMessage( "Fatal Error: Could not allocate needed memory!" );
      Close( );
    }

    // Read in the data
    fread( rom.data, 1, rom.Length, tf );
    fclose( tf );
    //---------------------------------//
    // Make sure it's the correct ROM  //
    // Usually ROM's Header Name       //
    //---------------------------------//
    if ( strncmp( &rom.data[0x07FFF5], "DOBULE MOON", 11 ) ){
      ShowMessage("Error: This is not the ROM used.\n"
                  "Please load the correct ROM."
                 );
      _free( rom.data );
      return;
    }
    //
    rom.Modified = false;
    // Try to open a Scripting File
    LoadDataFileClick( Sender );
    //
    if ( cmForm->bList->Items->Count <= 0 ) return;
    cmForm->bList->ItemIndex = 0;
    if ( cmForm->Visible ) cmForm->bList->SetFocus( );
    bListClick( NULL );
  }
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::SaveTextFile1Click(TObject *Sender)
{
  TxtForm->TDMemo->Lines->SaveToFile( AnsiString( txtf ) );
  ShowMessage( "\"" + AnsiString( ExtractFileName(txtf) ) + "\" was saved successfully!" );
  TxtForm->TDMemo->Modified = false;
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::Exit1Click(TObject *Sender)
{
  myForm->Close( );
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::bListClick(TObject *Sender)
{
  FILE *df;
  WORD cmpv;
  long valu;
  char buf[256],
       *p;

  // These have to be initialized first
  if ( !ram || !rom.data ) return;

  for ( int i = 0; i < cmForm->bList->Items->Count; i++ )
  { //
    if ( cmForm->bList->Selected[ i ] )
    { //
      txt.ptr_posi = lpTxtBlocks[ i ];
      //
      txt.Max_ptrs = (lpPointSize[ i ] - lpTxtBlocks[ i ]) >> 1;
      txt.posi     = i;

      // Decompress the data
      Decompress( txt.ptr_posi );

      // File the list box with data
      cmForm->pList->Clear( );
      for ( int c = 0; c < txt.Max_ptrs; c++ )
      {
        sprintf( buf, "String# %-5d", c );
        cmForm->pList->Items->Add( AnsiString( buf ) );
        // Add $10 for NES header adjustment
        lpTxtPoints[ c ] = (*(WORD *)&rom.data[ txt.ptr_posi + (c << 1) ]);
      }
      //------------------------//
      // Get new text file data //
      //------------------------//
      sprintf( buf, "%s\\%08X.txt", dirc, txt.ptr_posi );
//      strcpy( txtf, buf );
      if ( FileExists( AnsiString( txtf ) ) )
      { //
        if ( TxtForm->TDMemo->Modified ){
           int k = Application->MessageBox(
             "Current data not saved. Do you wish to save it?",
             "File Modified...",
             MB_ICONQUESTION + MB_YESNO
           );
           // If yes, save the file
           if ( k == ID_YES )
             SaveTextFile1Click( NULL );
        }
      }

      // Load new data
      strcpy( txtf, buf );
      if ( FileExists( AnsiString( txtf ) ) )
        TxtForm->TDMemo->Lines->LoadFromFile( AnsiString(txtf) );
      else
      { //
        if ( !FileExists( AnsiString( buf ) ) )
        { // Create the dump Data
          df = fopen( buf, "wt" );
          if ( df )
          { //
            fprintf( df, "// Do not erase these: \n// .STRING #\n// .ENDS\n\n\n" );
            for ( int c = 0; c < txt.Max_ptrs; c++ )
              fprintf( df, ".STRING %d\n\n\n\n.ENDS\n\n\n\n", c );

            // Close the file
            fclose( df );
          }// END IF - df
        }// END IF - File exist
      }

      //
      txt.posi         = i;
      cmForm->pList->ItemIndex = 0;
      cur_str          = 0;

      cmForm->pList->Hint      = IntToStr( cmForm->pList->Items->Count ) + " item(s)";
      pListClick( NULL );
      if ( cmForm->Visible ) cmForm->bList->SetFocus( );
      TxtForm->TDMemo->Modified = false;
    }// NEXT
  }
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::LoadDataFileClick(TObject *Sender)
{
  LONG x,y,z;
  int  cpos;
  CODE *tcode = NULL;
  char buf[560],
       cuf[560],
       arg1[32],
       arg2[32],
       var[16],
      *p;
  FILE *tf,
       *df;

  Open1->Title    = "Open Text Block Data File";
  Open1->Filter   = "Font Format File | *.txt";
  Open1->FileName = "";
  //
  if ( Open1->Execute( ) )
  { //
    tf = fopen( Open1->FileName.c_str( ), "rt" );
    if ( !tf ){
      ShowMessage("Fatal Error: Could not open FONT file!");
      return;
    }

    cnDraw       = false;
    // Release the last codes loaded
    for ( int c = 0; c < 0x10000; c++ ){
      _free( codes[c / 256].text );
      _free( duals[ c].text );
      codes[c / 256].color  = 0x0F;
      duals[ c ].color      = 0x0F;
      codes[ c / 256 ].type = 0;
      duals[ c ].type       = 0;
    }

    memset(buf, 0, 256);
    cmForm->bList->Clear( );
    cpos = 0;

    // get the format data
    while( fgets( buf, 256, tf ) )
    { //----------------------//
      // Textbox color data   //
      //----------------------//
      if ( !strncmpi(buf, ".textbox", 8) )
      { //
        sscanf( buf, "%s %s", &cuf, &arg1 );
        // Get the color
        if ( strstr( buf, ".color.blue") ) Blue1->Checked   = true;
        if ( strstr( buf, ".color.green")) Green1->Checked = true;
        if ( strstr( buf, ".color.red")  ) Red1->Checked   = true;
        // Get the color type
        if ( strstr( buf, ".solid" ) )     Solid1->Checked = true;
        if ( strstr( buf, ".gradient"))    Gradient1->Checked = true;        
      }

      //----------------------//
      //                      //
      //----------------------//
      if ( !strncmpi(buf, ".Font", 5) )
      {
        sscanf( buf, "%s %X", &cuf, &map.lpFontOffset );
      }
      //
      if ( !strncmpi(buf, ".TransText", 10) )
      {
        sscanf( buf, "%s %s", &cuf, &cuf );
        if ( !strcmpi( cuf, "SHOW" ) ){
          DTT->Checked = false;
          DTTClick( Sender );
        }
      }
      //----------------------//
      //                      //
      //----------------------//
      if ( !strncmpi(buf, ".CONTROLCODES", 13) )
      {
        sscanf( buf, "%s %s", &cuf, &cuf );
        if ( !strcmpi( cuf, "HIDE" ) ){
          HideCodes->Checked = false;
          HideCodesClick( Sender );
        }
      }
      //----------------------//
      //                      //
      //----------------------//
      if ( !strncmpi(buf, ".VWF", 4) )
      {
        sscanf( buf, "%s %s", &cuf, &cuf );
        if ( !strcmpi( cuf, "ON" ) ){
          UseVWFRoutine1->Checked = false;
          UseVWFRoutine1Click( Sender );
        }
      }
      //----------------------//
      //                      //
      //----------------------//
      if ( !strncmpi(buf, ".OffsetWindow", 13) )
      {
        sscanf( buf, "%s %s", &cuf, &cuf );
        if ( !strcmpi( cuf, "hide" ) ) cmForm->Visible = false; else cmForm->Visible = true;
      }
      //----------------------//
      //                      //
      //----------------------//
      if ( !strncmpi(buf, ".TextWindow", 11) )
      {
        sscanf( buf, "%s %s", &cuf, &cuf );
        if ( !strcmpi( cuf, "hide" ) ) TxtForm->Visible = false; else TxtForm->Visible = true;
      }

      //----------------------//
      //                      //
      //----------------------//
      if ( !strncmpi(buf, ".HexWindow", 10) )
      {
        sscanf( buf, "%s %s", &cuf, &cuf );
        if ( !strcmpi( cuf, "hide" ) ) HexForm->Visible = false; else HexForm->Visible = true;
      }
      //----------------------//
      //                      //
      //----------------------//
      if ( !strncmpi(buf, ".KanaWindow", 11) )
      {
        sscanf( buf, "%s %s", &cuf, &cuf );
        if ( !strcmpi( cuf, "hide" ) ) KanaForm->Visible = false; else KanaForm->Visible = true;
      }

      //----------------------//
      //                      //
      //----------------------//
      if ( !strncmpi(buf, ".FORMAT", 7) )
      { // goto _ReadGood;
        sscanf( buf, "%s   %d    %d  %d  %d   %d   %d %d %d %d",
                &buf[128],
                &map.cpl,
                &map.height,
                &map.width,
                &map.bpp,
                &map.inc,
                &map.set[0], &map.set[1],
                &map.set[2], &map.set[3]
              );
        //
        map.cpl *= map.inc;
      }

      //
      if ( !strncmpi(buf, ".BLOCK", 6) )
      { //
        x = y = z = 0;
        sscanf( buf, "%s %X %X %X", &cuf, &x, &y, &z );
        //
        sprintf( buf, "Block %X", x );
        //
        lpTxtBlocks[ cpos ] = x;
        lpPointSize[ cpos ] = y;
        lpTxtMaxPos[ cpos ] = z;
        lpTxtPoints[ cpos ] = 0;
        cpos++;
        //
        cmForm->bList->Items->Add( buf );
      }
      //---------------------------------------//
      // Check for color able index assignment //
      //---------------------------------------//
      if ( !strncmpi( buf, ".COLORTABLE", 6 ) )
      { //
        while( fgets( buf, 256, tf ) )
        { // Load the text value
          if ( !(x = strncmpi( buf, ".NULL=", 6)) || !(y = strncmpi( buf, ".NULL16", 7)) )
          {
            p = strchr( buf, '=' );
            if ( !p ) continue;
            *p = ' ';
            sscanf( buf, "%s %s", &cuf, &arg1 );
            //
            if ( !y ){
              // DUALS
              for ( int c = 0; c < 0x10000; c++ )
                if ( duals[c].type ) duals[c].color = GetIndex( arg1 );
            } else {
              // CODES
              for ( int c = 0; c < 0x00100; c++ )
                if ( codes[c].type ) codes[c].color = GetIndex( arg1 );
            }
          }
          else
          //----------------------------------//
          // Standard colors for table values //
          //----------------------------------//
          if ( p = strchr( buf, '=' ) )
          { //
            *p = ' ';
            z = (LONG)p - (LONG)buf;
            sscanf( buf, "%X %s", &x, &arg1 );
            //
            if ( z > 2 )
              tcode = &duals[x];
            else
              tcode = &codes[x];
            //
            tcode->color = GetIndex( arg1 );
          }
          else
          if ( strstr( buf, ".ENDCOLOR" ) )
            break;
          // end if
        }
      }
      //-------------------------//
      // Load up table file data //
      //-------------------------//
      if ( !strncmpi( buf, ".TABLE", 6 ) )
      { //
        while( fgets( buf, 256, tf ) )
        { // Load the text value
          if ( !(x = strncmpi( buf, ".NULL ", 6)) || !(y = strncmpi( buf, ".NULL16", 7)) )
          { //
            sscanf( buf, "%s %s %s %s", &cuf, &arg1, &cuf, &arg2 );
            //
            int  min = GetIndex( arg1 ),
                 max = GetIndex( arg2 );
            //
            if ( min > max ){
              x   = min;
              min = max;
              max = x;
            }
            //
            for ( int c = min; c <= max; c++ )
            { //
              tcode = ( (!x) ? &codes[c] : &duals[c] );
              //
              tcode->text = (BYTE *)malloc( 6 );
              if ( !tcode->text ){
                ShowMessage( "Error: Program outof memory. 'TABLE DATA Load'. " );
                fcloseall( ); Close( ); return;
              }
              //
              sprintf( tcode->text, "[$%02X]", c );
              tcode->type = 1;  // Make this a NULL code
            }

          }
          else
          if ( p = strchr( buf, '=' ) )
          { //
            *p = ' ';
            z = (LONG)p - (LONG)buf;
            //
            memset( cuf, 0, 256 );
            sscanf( buf, "%X %s", &x, &cuf );
            if ( z > 2 )
              tcode = &duals[x];
            else
              tcode = &codes[x];
            //
            tcode->length = strlen( cuf );
            memset( buf, 0, 256 );
            // Format string and get length
            if ( strstr( cuf, "\\" ) )
            { //
              tcode->length = 0;
              for ( int c = 0; c < strlen( cuf ); c++ )
              { //
                switch( cuf[ c ] )
                {
                  case '\\':
                    switch( cuf[ c + 1 ] ){
                      case 'x': c++; var[ 0 ] = cuf[ ++c ];
                                var[ 1 ] = cuf[ ++c ]; var[2] = 0;
                                buf[ tcode->length++ ] = strtoul( var, NULL, 16 ); break;
                      //--------------------------------------------
                      case 'n': c++; buf[ tcode->length++ ] = '\n'; break;
                      case 'r': c++; buf[ tcode->length++ ] = '\r'; break;
                      default : buf[ tcode->length++ ] = cuf[ c ]; break;
                    }
                    break;
                   //--------------------------------------------------
                   default : buf[ tcode->length++ ] = cuf[ c ]; break;
                }
              }
              //
              memset( cuf, 0, 256 );
              memcpy( cuf, buf, tcode->length + 1 );
            }
            //
            // Set the End of text BYTE
//            cuf[ tcode->length ] = 0xFF;
            tcode->text = (BYTE *)malloc( tcode->length + 1 );
            //
            if ( !tcode->text ){
              ShowMessage( "Error: Program outof memory. 'TABLE DATA Load'. " );
              fcloseall( ); Close( ); return;
            }
            //
            memcpy( tcode->text, cuf, tcode->length + 1 );
            //----------------------//
            // This means it's NULL //
            //----------------------//
            if ( !tcode->length )
            { //
              _free( tcode->text );
              tcode->text = (BYTE *)malloc( 6 );
              if ( !tcode->text ){
                ShowMessage( "Error: Program outof memory. 'TABLE DATA Load'. " );
                fcloseall( ); Close( ); return;
              }
              //
              sprintf( tcode->text, "[$%02X]", x );
              tcode->type = 1;  // Make this a NULL code
            }
          }
          else
          if ( strstr( buf, ".ENDTABLE" ) )
            break;
          // end if
        }
      }
    }
    // Load all block data
    fclose( tf );
    cnDraw = true;
    //
    myForm->Caption = "Script Editor: Legend of Double Moon - [ " + ExtractFileName( Open1->FileName ) + " ]";
     // Init the first block
    cmForm->bList->ItemIndex = 0;
    cmForm->bList->Hint = IntToStr( cmForm->bList->Items->Count ) + " item(s)";
    bListClick( NULL );
  }
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::FormCreate(TObject *Sender)
{
  WORD *VRAM;

  Vga = new Graphics::TBitmap;
  //
  if ( !Vga ){
    ShowMessage("Fatal Error: Could not acquire Video Pointer." );
    Close( );
    return;
  }

  // Starting directory
  getcwd( cur_dir, MAXPATH );

  Vga->Width       = Video->Width;
  Vga->Height      = Video->Height;
  Vga->PixelFormat = pf16bit;
  //
  txt.posi  = 0;
  txt.index = 0;
  //
  ScrBuf         = (WORD *)malloc( (Vga->Width * Vga->Height) << 2 );
  textbox[0].pic = (WORD *)malloc( (0x39000 << 2) );
  textbox[1].pic = (WORD *)malloc( (0x39000 << 2) );
  //
  ram  = (BYTE *)malloc( 0x20000 );
  EStr = (BYTE *)malloc( 0x20000 );
  if ( !ram || !ScrBuf || !textbox[0].pic || !textbox[1].pic || !EStr ){
    ShowMessage("Fatal Error: Could not allocate memory!" );
    myForm->Close( );
    return;
  }
  //
  memsetw( ScrBuf, 0x0000, Vga->Width * Vga->Height );
  memset( ram , 0, 0x20000 );
  memset( EStr, 0, 0x20000 );
  textbox[0].height = 0x0300;
  textbox[1].height = 0x0300;
  //
  WinX = myForm->ClientWidth;
  WinY = myForm->ClientHeight;
  // Assign default colors to codes
  for ( int c = 0; c < 0x10000; c++ )
    codes[(c / 256)].color =
    duals[ c ].color       = 15;
  //

  for ( int y = 0; y < Vga->Height; y++ )
  { //
    (void *)VRAM = Vga->ScanLine[ y ];
      memset( VRAM, 0, Vga->Width << 1);
  }
  Video->Canvas->StretchDraw( Video->ClientRect, Vga );

  isActive = true;
//  Application->OnMessage = AppMessage;
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::FormClose(TObject *Sender, TCloseAction &Action)
{
  int  k;

  isActive = false;

  //
  if ( TxtForm && TxtForm->TDMemo->Modified )
  { //
    k = Application->MessageBox(
      "Current data not saved. Do you wish to save changes made?",
      "TEXT File Modified...",
      MB_ICONQUESTION + MB_YESNO
    );
    // If yes, save the file
    if ( k == ID_YES )
      SaveTextFile1Click( NULL );
  }
  //
  if ( rom.Modified )
  { //
    k = Application->MessageBox(
      "ROM data modified. Do you wish to save changes?",
      "ROM File Modified...",
      MB_ICONQUESTION + MB_YESNO
    );
    // If yes, save the file
    if ( k == ID_YES )
      SaveRomFile1Click( NULL );
  }

  _free( rom.data );
  _free( ram );
  _free( EStr );  
  _free( ScrBuf );
  _free( textbox[0].pic );
  _free( textbox[1].pic );
  //
  for ( int c = 0; c < 0x10000; c++ ){
    _free( table.tbl[ c / 256 ] );
    _free( table.dte[ c / 256 ] );
    _free( table.dbl[ c / 256 ] );
    //
    _free( codes[ c / 256 ].text );
    _free( duals[ c ].text );
  }
  //
  if ( Vga ) delete Vga;
  if ( HexForm && HexForm->PIC ) delete HexForm->PIC;
  //
  exit( 0 );
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::DrawText( int  skip, int height, int width, LONG fnPosition )
{
  #define StartX     0
  #define StartY     8
  #define MASK_COLOR 0x11

  #define BLACK      0x00
  #define BLUE       0x01
  #define GREEN      0x02
  #define TEAL       0x03
  #define RED        0x04
  #define PURPLE     0x05
  #define BROWN      0x06
  #define GRAY       0x07

  #define CHARCOAL   0x08
  #define LtBLUE     0x09
  #define LtGREEN    0x0A
  #define LtTEAL     0x0B
  #define LtRED      0x0C
  #define LtPURPLE   0x0D
  #define YELLOW     0x0E
  #define WHITE      0x0F

  LONG tilep;
  LONG cpOffset;

  char buf[256],
       *p;
  WORD *VRAM;
//  static WORD *ScrBuf;
  static TBOX *myBox;
  WORD val[4];
  BYTE *TEMP    = NULL,
       COLR,
       TCOLR,
       BITS,
       BUFR[256],
       TILE[16][16],
       flag = 0,
       VWF;

  // Make sure we can do this!
  if ( !rom.data || !ram || !cnDraw ) return;
  if ( !map.cpl ){
    map.cpl    = 18;
    map.height = 8;
    map.width  = 8;
    map.bpp    = 1;
    map.inc    = 8;
    map.set[0] = 0;
    map.set[1] = 1;
    map.set[2] = 2;
    map.set[3] = 3;
    map.cpl *= map.inc;
    //
    return;
  }

  //-------------------------------------------//
  // If SKIP is active, this means we          //
  // are drawing Control codes and compression //
  //-------------------------------------------//
  if ( !skip )
  { // Get the Text pointer and display the text!
//    ScrBuf = textbox[ (int)DTT->Checked ].pic;
    myBox      = &textbox[ (int)DTT->Checked ];
    memsetw( myBox->pic, 0, 0x39000 );
    memset( &men, 0, sizeof(TMEN) );
    //
    txt.tColor = 15;
    txt.data   = 0;
    men.Ypos   = 0;
    men.Xpos   = 0;

    // Select which text box to use
    txt.xpos   = StartX;
    txt.ypos   = StartY;
    if ( !DTT->Checked ) memsetw( ScrBuf, 0, (Vga->Width * Vga->Height) );
    //------------------------//
    // Check to see if we use //
    // the ROM or the buffer  //
    //------------------------//
    if ( DTT->Checked )
    { //
      txt.TextBuf  = EStr;
      map.cpl      = 31 << 3;
      men.Xdim     = 31;
      height       = 8;
      width        = 8;
      myBox->width = men.Xdim << 3;
    }
    else
    {
      txt.pntr    = lpTxtPoints[ txt.ptr_index ] + 0x10;
      // Check for valid pointer
      if ( (txt.pntr & 0x3FFF) >= (lpPointSize[ txt.posi ] & 0x3FFF) )
//      txt.pntr    = *(WORD *)&rom[ ( (txt.ptr_posi & 0xFF0000) | (txt.pntr & 0x7FFF) ) ];
        if ( (lpTxtBlocks[ txt.posi ] & 0x4000) )
          txt.TextBuf = &rom.data[ ((txt.ptr_posi & 0xFFC000) | (txt.pntr & 0x7FFF)) ];
        else
        if ( (lpTxtBlocks[ txt.posi ] & 0x8000) )
          txt.TextBuf = &rom.data[ ((txt.ptr_posi & 0xFF8000) | (txt.pntr & 0x7FFF)) ];
        else
          txt.TextBuf = &rom.data[ ((txt.ptr_posi & 0xFF0000) | (txt.pntr & 0x7FFF)) ];
      else {
        sprintf( buf, "NON-VALID POINTER - $%04X\xFF", txt.pntr - 0x10 );
        txt.TextBuf = buf;
        height      = 8;
        width       = 5;
        flag        = 1;
      }
      //
//      men.Xdim    = map.cpl >> 3;
      map.cpl      = 304;
      men.Xdim     = map.cpl >> 3;
      myBox->width = men.Xdim << 3;
    }
    //
    if ( !DTT->Checked ){
      // Draw the hex data
      HexForm->DrawHex( txt.TextBuf );
      // Draw the text data
      KanaForm->ShowText( txt.TextBuf, flag );
    }
  }

  //------------------------------------//
  // Display the text data              //
  //------------------------------------//
  while( txt.data != 0xFF )
  { //
    txt.data     = txt.TextBuf[0];
    txt.TextBuf += 1;

    //-------------//
    // Dual table  //
    //-------------//
    if ( duals[ (txt.data << 8) + txt.TextBuf[0] ].length &&
         duals[  (txt.data << 8) + txt.TextBuf[0] ].text[0] < 0x7F
       )
    { // We have a code table value
      txt.data     = (txt.data << 8) | txt.TextBuf[0];
      txt.TextBuf += 1;
      //
      TEMP        = txt.TextBuf;
      sprintf( buf, "%s\xff", (char *)duals[ txt.data ].text );
      //
      if ( (p = strchr( buf, '\r' )) )
        *p = 0xFC;
      if ( (p = strchr( buf, '\n' )) ) *p = ' ';
      //
      txt.TextBuf = buf;
      COLR        = txt.tColor;
      txt.tColor  = duals[ txt.data ].color;
      // Hide these codes?
      if ( !HideCodes->Checked )
        DrawText( true, 8, 5, fnPosition );
      //
      txt.tColor  = COLR;
      txt.TextBuf = TEMP;
      TEMP        = NULL;
      continue;
    }

    //-------------//
    // Code table  //
    //-------------//
    if ( codes[ txt.data ].length && codes[ txt.data ].text[0] < 0x7F )
    { // We have a code table value
      sprintf( buf, "%s\xff", (char *)codes[ txt.data ].text );
      //
      if ( (p = strchr( buf, '\r' )) )
        *p = 0xFC;
      if ( (p = strchr( buf, '\n' )) ) *p = ' ';
      //
      TEMP        = txt.TextBuf;
      txt.TextBuf = buf;
      COLR        = txt.tColor;
      txt.tColor  = codes[ txt.data ].color;
      // Hide these codes?
      if ( !HideCodes->Checked )
        DrawText( true, 8, 5, fnPosition );
      //
      txt.tColor  = COLR;
      txt.TextBuf = TEMP;
      TEMP        = NULL;
      continue;
    }

    //----------------------------//
    // Check for Null assignments //
    //----------------------------//
    if ( duals[ (txt.data << 8) + txt.TextBuf[0] ].type )
    {
      txt.data     = (txt.data << 8) | txt.TextBuf[0];
      txt.TextBuf += 1;
      //
      TEMP        = txt.TextBuf;
      sprintf( buf, "[$%04X]\xff", txt.data  );
      txt.TextBuf = buf;
      COLR        = txt.tColor;
      txt.tColor  = duals[ txt.data ].color;
      //
      DrawText( true, 8, 5, fnPosition );
      //
      txt.tColor  = COLR;
      txt.TextBuf = TEMP;
      TEMP        = NULL;
      continue;
    }
    //
    if ( codes[ txt.data ].type )
    { //
      TEMP        = txt.TextBuf;
      sprintf( buf, "[$%02X]\xff", txt.data  );
      txt.TextBuf = buf;
      COLR        = txt.tColor;
      txt.tColor  = codes[ txt.data ].color;
      //
      DrawText( true, 8, 5, fnPosition );
      //
      txt.tColor  = COLR;
      txt.TextBuf = TEMP;
      TEMP        = NULL;
      continue;
    }

    // Standard data checking
    if ( txt.data >= 0x80 )
    { //
      if ( txt.data < 0xB1 )
      { //
        cpOffset       = 0x79F98 + (( txt.data << 1 ) & 0xFF);
        txt.data       = rom.data[ cpOffset++ ];
        txt.ypos      -= 8;
        TEMP = txt.TextBuf;
        sprintf( buf, "%c\xFF", txt.data );
        txt.TextBuf    = buf;
        //
        DrawText( true, 8, 8, fnPosition );
        //
        txt.ypos   += 8;
        txt.xpos   -= 8;
        txt.TextBuf = TEMP;
        TEMP        = NULL;
        txt.data       = rom.data[ cpOffset++ ];
        //
      }
    }
    //----------------//
    // End Text Write //
    //----------------//
    if ( txt.data == 0xFF )
    { //
      txt.data = 0;
      if ( skip ) return;
      break;
    }
    else
    //-------------//
    // Line break  //
    //-------------//
    if ( txt.data == 0xFC )
    { //
      _Bah:
      txt.data  = 0;
      txt.ypos += height;
      txt.ypos += height;
      txt.xpos  = StartX;
      men.Ydim += 2;
      continue;
    }


    //-----------------------------//
    // Font size testing done here //
    // decode the ROM's font       //
    //-----------------------------//
    if ( !DTT->Checked && !flag && width == 8 )
    { // Font matches the ROM's size AND Display Translated Text is INACTIVE
      // Display the text
      // Decode the ROM's font
      txt.tpos  = (txt.data * 0x10) & 0xFFFF;
      memset( TILE, 0, 256 );
      //
      memcpy( BUFR, &rom.data[ (fnPosition + txt.tpos) ], 0x10 );
      // Convert the tile data
      int x = -1;
      while( ++x < 8 )
        Dec2Bin( &txt.tile[ x * width ], BUFR[ x + 8 ], 8, 2 );
      //
    }
    else
    //-----------------------------//
    // My font used for Trans Text //
    //-----------------------------//
    if ( !skip && DTT->Checked )
    { // Display Translated Text is ACTIVE, use 16x16 font [ Menu.cpp ]
      //
      memcpy( BUFR, &FONT8x8[ (txt.data & 0xFF) << 3 ], 0x08 );
      memset( txt.tile, 0, 256 );
      // Convert the tile data
      int x = -1;
      while( ++x < 8 )
        Dec2Bin( &txt.tile[ x * width ], BUFR[ x ], 8, 0 );
    }
    else
    //--------------------------------//
    // My font used for Control Codes //
    //--------------------------------//
    { // 5 x 8 font. control codes [ Menu.cpp ]
      memcpy( BUFR, &FONT5x8[ (txt.data & 0xFF) << 3 ], 0x8 );
      memset( txt.tile, 0, 256 );
      // Convert the tile data
      int x = -1;
      while( ++x < 8 )
        Dec2Bin( &txt.tile[ x * width ], BUFR[ x ], 8, 0 );
    }

    //---------------//
    // DMA to Vram   //
    //---------------//
    VWF       = 0;
    txt.ypos %= myBox->height;
    //
    for ( int y = 0; y < height; y++ )
    { //
      for ( int x = 0; x < width; x++ )
      { //
        if ( txt.tile[ (y * width) + x ] )
        { // Add pixel
          myBox->pic[ ((txt.ypos + y) * myBox->width) + (txt.xpos + x + 0) ]     = DOS565[ txt.tColor ];
          // Add Shadow on the side
          myBox->pic[ ((txt.ypos + y) * myBox->width) + (txt.xpos + x + 1) ]     = DOS565[ MASK_COLOR ];
          // Add Shadow on the bottom + side
//          myBox->pic[ ((txt.ypos + y + 1) * myBox->width) + (txt.xpos + x + 1) ] = DOS565[ MASK_COLOR ];
          // For VWF routine
          if ( x > VWF ) VWF = x;
          // For some reason single pixel
          // fonts don't record a value
          if ( !VWF ) VWF = 1;
        }
        else
        { //
          if ( myBox->pic[ ((txt.ypos + y) * myBox->width) + (txt.xpos + x + 0) ] != DOS565[ MASK_COLOR ] )
            myBox->pic[ ((txt.ypos + y) * myBox->width) + (txt.xpos + x + 0) ] = DOS565[ 0 ];
        }
        //
      }
    }// NEXT y

    //-------------------------------//
    // VWF routine for Control Codes //
    // or if Use VWF Active          //
    //-------------------------------//
    if ( (skip && (width == 5 && height == 8)) || flag )
    { //
      if ( !VWF ) VWF = 6;

      txt.xpos += (VWF + 2);
    }
    else
      txt.xpos += 8;

    //----------------------------------------//
    // Check Width boundaries for NON-English //
    //----------------------------------------//
    if ( !DTT->Checked && txt.xpos >= map.cpl )
    { //
      txt.xpos  = StartX;
      txt.ypos += 0x10;
      men.Ydim += 2;
    }
    //----------------------------------------//
    // Check Width boundaries for NON-English //
    //----------------------------------------//
    if ( DTT->Checked && txt.xpos >= ((men.Xdim << 3) - 16) )
    { //
      txt.xpos  = StartX;
      txt.ypos += 0x10;
      men.Ydim += 2;
    }
  }

  //----------------------------------------------//
  // Build Map, Draw the Menu, masking enabled    //
  //----------------------------------------------//
  men.Ydim                = 14;
  men.menu[0][0]          = 1;
  men.menu[0][men.Xdim-1] = 3;
  memset( &men.menu[0][1], 2, men.Xdim - 2 );
  //
  men.menu[men.Ydim-1][0]          = 6;
  men.menu[men.Ydim-1][men.Xdim-1] = 8;
  memset( &men.menu[men.Ydim-1][1], 7, men.Xdim - 2 );
  //
  for ( int y = 1; y < men.Ydim-1; y++ )
  { //
    men.menu[y][0]          = 4;
    men.menu[y][men.Xdim-1] = 5;
  }
  //-----------------------------//
  // Which box to draw & display //
  //-----------------------------//
  if ( !DTT->Checked )
    MenuMap( &ScrBuf[(0x08 * Vga->Width) + 8], &men, Vga->Width, 0 );
  else
    MenuMap( &ScrBuf[(0x88 * Vga->Width) + 8], &men, Vga->Width, 0 );
  //
  myBox->Xpos = (DTT->Checked ? 0x88 : 0x08);
  //
  int  ypos = (DTT->Checked ? 0x88 : 0x08);
  for ( int y = 0; y < ((men.Ydim+0) << 3); y++ )
  { //
    (void *)VRAM = Vga->ScanLine[ y + myBox->Xpos ];
     memcpyw( VRAM, &ScrBuf[ (y + ypos) * Vga->Width ], Vga->Width, 0 );
  }// NEXT y
  //
  myBox->Xpos = (DTT->Checked ? 0x90 : 0x10);
  //
  for ( int y = 0; y < 96; y++ )
  { //
    (void *)VRAM = Vga->ScanLine[ (y + myBox->Xpos) ];
     // Draw the Text data
     memcpyw( &VRAM[16], &myBox->pic[ ((y + myBox->Ypos) * myBox->width) ], myBox->width, 2 );
  }// NEXT y

  Video->Canvas->StretchDraw( Video->ClientRect, Vga );
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::VideoPaint(TObject *Sender)
{
  if ( rom.data )
    Video->Canvas->StretchDraw( Video->ClientRect, Vga );
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::pListClick(TObject *Sender)
{
  #define LINE_BREAK 0xFC
  #define TEXT_BREAK 0xFF
  #define STRING_END 0x00

  POINT caret;
  long valu,
       c_test,
       pos;
  WORD inPosi,
       strLength;
  char buf[256],
       tuf[256];
  char conv[16],
       flag,
       *p1,
       *p2;
/*  char *codes [ ] =
  {
    "ClrScr", "\xFB",
    "Player", "\xCC",
    "Key"   , "\xFD",
    "YES-NO", "\xFE",
    "\0"    , "\0"
  };
*/

  if ( !ram || !rom.data ) return;
  //
  for ( int k = 0; k < cmForm->pList->Items->Count; k++ )
  { //
    if ( cmForm->pList->Selected[ k ] )
    { //---------------------//
      // Draw the Kana First //
      //---------------------//

      // Do this ONLY if we don't want to insert text
      // reset scrolling positions
      if ( !TxtForm->Active ) {
        textbox[0].Ypos = 0;
        textbox[1].Ypos = 0;
      }
      //
      DTT->Checked = false;
      txt.ptr_index = k;
      DrawText( false, map.height, map.width, map.lpFontOffset );
      // Get to the string Location
      //
      KanaForm->Caption = "Kana Text: String #" + IntToStr( k );

      sprintf( buf, ".STRING %d", k );
      // Disable the Main window
      Find1->FindText  = AnsiString( buf );

      if ( (LONG)Sender == 1 )
        Find1Find( (TObject *)1 );
      else
        Find1Find( NULL );
      //------------------------------//
      // Build translated text string //
      //------------------------------//
      if ( indexLine != -1 )
      { // Clear the buffer
        // copy text to temp buffer
        TxtForm->Memo1->Clear( );
        valu = 0;
        //
        while( Trim( TxtForm->TDMemo->Lines->Strings[ indexLine + valu ] ) != ".ENDS" )
          TxtForm->Memo1->Lines->Add( TxtForm->TDMemo->Lines->Strings[ indexLine + valu++ ] );
        //
        TxtForm->Memo1->Lines->Add( TxtForm->TDMemo->Lines->Strings[ indexLine + valu ] );

        memset( EStr, 0, sizeof( EStr ) );
        inPosi = 0;
        //---------------------------//
        //                           //
        //---------------------------//
//        for ( int i = indexLine+1; i < TxtForm->TDMemo->Lines->Count; i++ )
        for ( int i = 1; i < TxtForm->Memo1->Lines->Count; i++ )
        { //
//          strcpy( buf, TxtForm->TDMemo->Lines->Strings[ i ].c_str( ) );
          strcpy( buf, TxtForm->Memo1->Lines->Strings[ i ].c_str( ) );
          strLength = strlen( buf );
          // Conversion Loop
          for ( int c = 0; c < strLength; c++ )
          { //-------------------------//
            // Check for control codes //
            //-------------------------//
            c_test = 0;
            flag   = 0;
            //
            while( c_test < 256 )
            { // Do some comparisons
              memset( tuf, 0, 256 );
              pos = -1;
              while( ++pos < codes[ c_test ].length ){
                if ( codes[ c_test ].text[ pos ] < 0x7F && codes[ c_test ].text[ pos ] > 0x1F )
                  tuf[ pos ] = codes[ c_test ].text[ pos ];
                else {
                  tuf[ pos ] = 0;
                  break;
                }
              }

              //
              if ( pos && !strncmpi( &buf[c], tuf, strlen( tuf ))
                 )
              { //
                EStr[ inPosi++ ] = c_test;
                // Advance Testing DAta's curent position
                c += strlen( tuf ) - 1;
                // If this is true, do NOT set the flag!
                if ( buf[ c ] == '$' ) break;
                // We found what we need! No more test
                flag = 1;
                // Decrementc since it's part of a FOR loop
                break;
              } // END IF
              //
              c_test++;
            }

            // If FLAG still zero, no code match was found!
            if ( !flag )
            { // Check for HEX Only codes
              if ( buf[c] == '$')
              { //
                c++;
                while( buf[c] != ']' ){
                  memcpy( conv, &buf[c], 2 ); conv[ 2 ] = 0;
                  EStr[ inPosi++ ] = strtol( conv, NULL, 16 );
                  c += 2;
                }
                //
                EStr[ inPosi ] = STRING_END;
              }
              else
              { // If it comes here then it's regular data
                EStr[ inPosi++ ] = buf[ c ];
                EStr[ inPosi   ] = STRING_END;
              }
            } // END IF

          } // END IF - Control Codes

          // Add the Line Break if needed
//          strcpy( buf, TxtForm->TDMemo->Lines->Strings[ i + 1 ].c_str( ) );
          strcpy( buf, TxtForm->Memo1->Lines->Strings[ i + 1 ].c_str( ) );
          if ( !strncmpi( buf, ".ENDS", 5) ){
            EStr[ inPosi++ ] = TEXT_BREAK;
            EStr[ inPosi   ] = STRING_END;
            break;
          } else {
            EStr[ inPosi++ ] = LINE_BREAK;
            EStr[ inPosi   ] = STRING_END;
          }
        } // NEXT i

        //
        DTT->Checked = true;
        DrawText( false, 8, 8, map.lpFontOffset );
        DTT->Checked = false;
      }

      //--------------------//
      //                    //
      //--------------------//
      sprintf( buf, "Offset: %06X | PTR: %04X -> %06X",
                    ((txt.ptr_posi & 0xFF8000)| txt.pntr) - 0x10,
                    (txt.pntr - 0x10),
                    (txt.ptr_posi + (txt.ptr_index << 1)) - 0x10
             );
      //
      StatusBar1->Panels->Items[0]->Text = AnsiString( buf );
      StatusBar1->Panels->Items[1]->Text = "Line {Kana, Ascii}: " + IntToStr( (textbox[0].Ypos >> 4) ) + ", " + IntToStr( (textbox[1].Ypos >> 4) );
//      if ( Sender && cmForm->Visible) cmForm->pList->SetFocus( );
      if ( Sender && (LONG)Sender != 1 && cmForm->Visible ) cmForm->pList->SetFocus( );
      break;
    }
  }
}




//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::Find1Find(TObject *Sender)
{
  // begin the search after the current selection
  // if there is one
  // otherwise, begin at the start of the text
  if ( TxtForm->TDMemo->SelLength )
    StartPos = TxtForm->TDMemo->SelStart + TxtForm->TDMemo->SelLength;
  else

    StartPos = 0;

  // ToEnd is the length from StartPos
  // to the end of the text in the rich edit control

  ToEnd   = TxtForm->TDMemo->Text.Length( ) - StartPos;

  FoundAt = TxtForm->TDMemo->FindText( Find1->FindText, StartPos, ToEnd, TSearchTypes( ) );
  //

  if ( FoundAt != -1 )
  {
//    if ( TxtForm->Visible ) TxtForm->TDMemo->SetFocus( );
    TxtForm->TDMemo->SelStart  = FoundAt;
    TxtForm->TDMemo->SelLength = 0;
    //
    curLine              = TxtForm->TDMemo->Perform( EM_GETFIRSTVISIBLELINE, 0, 0 );
    if ( TxtForm->TDMemo->Text.Length( ) > 0xFFFF )
      indexLine          = TxtForm->TDMemo->Perform( EM_EXLINEFROMCHAR, FoundAt, 0 );
    else
      indexLine          = TxtForm->TDMemo->Perform( EM_LINEFROMCHAR, FoundAt, 0 );
    //
//    if ( (LONG)Sender != 1 )
    if ( !(LONG)Sender )
      TxtForm->TDMemo->Perform( EM_LINESCROLL, 0, indexLine - curLine );
  }
  else
  {
    indexLine = -1;
  }
}


//---------------------------------//
//                                 //
//---------------------------------//
long __fastcall TmyForm::GetCurLine( long valu )
{
  DWORD both = 0;
  int indexLine;
  int indexLength;

  both        = MAKELPARAM( (valu >> 16) & 0xFFFF, (valu >> 0 ) & 0xFFFF );
  indexLine   = TxtForm->TDMemo->Perform( EM_LINEFROMCHAR, -1, 0 );
  indexLength = (LOWORD(both)/8) + TxtForm->TDMemo->SelLength;

  return indexLine;
}


//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::DisplayTextEditor1Click(TObject *Sender)
{
  TxtForm->Show( );
}


//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::HideCodesClick(TObject *Sender)
{
/*
  char *str[4] = { "Visible", "Hidden", "Inactive", "Active" };
  //
  HideCodes->Checked ^= 1;
  DrawText( false, map.height, map.width, map.lpFontOffset );
  //
  StatusBar1->Panels->Items[1]->Text = "Control Codes: " + AnsiString( str[ HideCodes->Checked & 1 ] ) + " | VWF: " + AnsiString( str[ (UseVWFRoutine1->Checked & 1) + 2 ] );
*/
}


//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::UseVWFRoutine1Click(TObject *Sender)
{
/*
  char *str[4] = { "Visible", "Hidden", "Inactive", "Active" };
  //
  UseVWFRoutine1->Checked ^= 1;
  DrawText( false, map.height, map.width, map.lpFontOffset );
  //
  StatusBar1->Panels->Items[1]->Text = "Control Codes: " + AnsiString( str[ HideCodes->Checked & 1 ] ) + " | VWF: " + AnsiString( str[ (UseVWFRoutine1->Checked & 1) + 2 ] );
*/
}


//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::DTTClick(TObject *Sender)
{
  DTT->Checked ^= true;
  //
  pListClick( Sender );
}

//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::ViewHexData1Click(TObject *Sender)
{
  HexForm->Show( );
}


//--------------------------------------------//
// The Decompression Routine for ROM Name     //
//--------------------------------------------//
long __fastcall TmyForm::Decompress( LONG  index )
{
  LONG offset;
  WORD posi;
  BYTE *comp;
  FILE *rf;
  char buf[MAXPATH];

  //----------------------------//
  // Text decompression routine //
  //----------------------------//
  offset     = Snes2Pc( index, 0 );

  return offset;
}


//------------------------//
//                        //
//------------------------//
void __fastcall TmyForm::DecompresstoFiles1Click(TObject *Sender)
{
  cmForm->Show( );
}


//------------------------//
//                        //
//------------------------//
void __fastcall TmyForm::DumpMemory1Click(TObject *Sender)
{
  FILE *sf;

  FSave->InitialDir = cur_dir;
  FSave->Title      = "Dump \ Working RAM to file...";

  if ( FSave->Execute( ) )
  { //
    sf = fopen( FSave->FileName.c_str( ), "wb" );
    if ( !sf ){
      ShowMessage( "Error: Could not open file for saving..." );
      return;
    }
    //
    fwrite( ram, 1, 0x20000, sf );
    fclose( sf );
  }
}


//------------------------//
//                        //
//------------------------//
void __fastcall TmyForm::Red1Click(TObject *Sender)
{
  TMenuItem *m = (TMenuItem *)Sender;

  m->Checked = true;

  // Kana
  DTT->Checked = false;
  DrawText( false, map.height, map.width, map.lpFontOffset );
  // Ascii
  DTT->Checked = true;
  DrawText( false, map.height, map.width, map.lpFontOffset );
  DTT->Checked = false;
}


//------------------------//
//                        //
//------------------------//
void __fastcall TmyForm::Zoominx11Click(TObject *Sender)
{
  if ( myForm->WindowState == wsMaximized )
    myForm->WindowState = wsNormal;
  //
  myForm->ClientHeight = WinY + 256;
  myForm->ClientWidth  = WinX << 1;
  //
  FormResize( NULL );
}


//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::DefaultWindowSize1Click(TObject *Sender)
{
  if ( myForm->WindowState == wsMaximized )
    myForm->WindowState = wsNormal;
  //
  myForm->ClientHeight = WinY;
  myForm->ClientWidth  = WinX;
  //
  FormResize( myForm );
}


//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::DisplayKanaTextDump1Click(TObject *Sender)
{
  KanaForm->Show( );
}


//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::FormResize(TObject *Sender)
{
  //
  if ( isActive == false ) return;
  //
  if ( myForm->WindowState == wsNormal )
  {
    TxtForm->Top  = myForm->Top;
    TxtForm->Left = myForm->Left + myForm->Width + 2;
    //
    cmForm->Top  = TxtForm->Top + TxtForm->Height + 2;;
    cmForm->Left = TxtForm->Left;
    //
    if ( Sender != NULL )
    {
      KanaForm->Left = myForm->Left;
      KanaForm->Top  = myForm->Top + myForm->Height + 2;
    }
    else
    {
      KanaForm->Left = cmForm->Left;
      KanaForm->Top  = cmForm->Top + cmForm->Height + 2;
    }
  }
}


//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::TEOnTopClick(TObject *Sender)
{
  TEOnTop->Checked ^= true;
  //
  if ( TEOnTop->Checked )
  {
    TxtForm->FormStyle = fsStayOnTop;
    KanaForm->FormStyle = fsStayOnTop;
  }
  else
  {
    TxtForm->FormStyle = fsNormal;
    KanaForm->FormStyle = fsNormal;
  }
}


//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
{
  TBOX *myBox = NULL;

  if ( Shift.Contains( ssShift) ) myBox = &textbox[0];
  if ( Shift.Contains( ssCtrl ) ) myBox = &textbox[1];

  if ( myBox )
  {
    switch( Key )
    {
      case VK_UP  : if ( myBox->Ypos ) myBox->Ypos -= 16; else Key = 0; break;
      case VK_DOWN: if ( (myBox->Ypos + 96) < 0x300 ) myBox->Ypos += 16; else Key = 0; break;
      default     : Key = 0; break;
    }
  }

  // Kana
  if ( Key )
  {
    DTT->Checked = false;
    DrawText( false, map.height, map.width, map.lpFontOffset );

    // Ascii
    DTT->Checked = true;
    DrawText( false, map.height, map.width, map.lpFontOffset );
    DTT->Checked = false;
    //
//    StatusBar1->Panels->Items[1]->Text = "Kana line: " + IntToStr( (textbox[0].Ypos >> 4) ) + " | ASCII line: " + IntToStr( (textbox[1].Ypos >> 4) );
    StatusBar1->Panels->Items[1]->Text = "Line {Kana, Ascii}: " + IntToStr( (textbox[0].Ypos >> 4) ) + ", " + IntToStr( (textbox[1].Ypos >> 4) );
  }
}


//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::SaveRomFile1Click(TObject *Sender)
{
  FILE *rf = NULL;

  if ( !rom.data || !ram ) return;
  //
  rf = fopen( romf, "wb" );
  if ( !rf )
  { //
    ShowMessage( "Fatal Error: Could not open ROM File for saving..." );
    return;
  }
  //
  fwrite( rom.data, 1, rom.Length, rf );
  fclose( rf );
  //
  if ( isActive )
    ShowMessage( "ROM File saved successfully!" );
  //
  rom.Modified = false;
}


//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::InsertTextFiletoRom1Click(TObject *Sender)
{
  TPTR *pointer = NULL;
  TBUF temp;
  char buf[16];
  char string[1024];
  LONG ptr_posi,
       count,
       cur_posi,
       text_size;


  if ( !rom.data || !ram ) return;

  // This game requires a table file
  if ( !tblf[0] ){
    ShowMessage( "Error: Must load a table file first!" );
    return;
  }
  //

  // Unselect sorting first
  ptrBox->Sorted = false;
  // Clear data
  ptrBox->Clear( );
  // Load up pointers
  for ( int c = 0; c < txt.Max_ptrs; c++ )
  { //
    txt.pntr    = lpTxtPoints[ c ] + 0x10;
    // Check for valid pointer
    if ( (txt.pntr & 0x3FFF) >= (lpPointSize[ txt.posi ] & 0x3FFF) )
    {
      sprintf( buf, "%08X  %3d", lpTxtPoints[ c ], c );
      ptrBox->Items->Add( buf );
    }
  }

  // Get memory
  count = ptrBox->Items->Count;
  (BYTE *)pointer = (BYTE *)malloc( count * sizeof(TPTR) );
  if ( !pointer )
  {
    ShowMessage(
      "Fatal Error: Could not acquire needed memory.\n"
      "             Closing program..."
    );
    //
    _free( pointer );
    Close( );
    return;
  }
  //
  memset( (BYTE *)pointer, 0, sizeof(TPTR) * count );
  // Reselect sorting
  ptrBox->Sorted = true;


  //----------------------------------//
  // Find END of TEXT if not declared //
  //----------------------------------//
  temp           = txt;
  //
  if ( !lpTxtMaxPos[ txt.posi ] )
  { // Save the current data
    txt.data       = 0;
    //
    sscanf( ptrBox->Items->Strings[ ptrBox->Items->Count-1 ].c_str( ), "%s %d", &buf, &txt.ptr_index );
    txt.pntr       = lpTxtPoints[ txt.ptr_index ] + 0x10;
    //
    if ( (lpTxtBlocks[ txt.posi ] & 0x4000) )
      txt.TextBuf = &rom.data[ cur_posi = ((txt.ptr_posi & 0xFFC000) | (txt.pntr & 0x7FFF)) ];
    else
    if ( (lpTxtBlocks[ txt.posi ] & 0x8000) )
      txt.TextBuf = &rom.data[ cur_posi = ((txt.ptr_posi & 0xFF8000) | (txt.pntr & 0x7FFF)) ];
    else
      txt.TextBuf = &rom.data[ cur_posi = ((txt.ptr_posi & 0xFF0000) | (txt.pntr & 0x7FFF)) ];
    //
    // Get the last pointer and find the end of text
    count = 0;
    while( txt.TextBuf[ count ] != 0xFF && (cur_posi + count) < rom.Length )
      count++;
    //
    if ( (cur_posi + count) >= rom.Length )
    {
      ShowMessage(
        "Error: Could not find \"End of Text\"."
        "       You can manually set the \"End of Text\" like so"
        "       in the Format text file. \".ENDBLOCK $offset\"."
       );
       //
       _free( pointer );
       return;
    }
    //
    lpTxtMaxPos[ txt.posi ] = (cur_posi + count);
  }

  //---------------------------------------//
  // Translate the raw text to usable data //
  //---------------------------------------//
  for ( int c = 0; c < ptrBox->Items->Count; c++ )
  {
    sscanf( ptrBox->Items->Strings[ c ].c_str( ), "%X %d", &cur_posi, &count );
    txt.pntr    = cur_posi + 0x10;
    // Position in table to store POINTER
    pointer[ c ].Position = count;
    pointer[ c ].Length   = Text2Raw( count );
    // Make sure it's a valid pointer
    if ( !pointer[ c ].Length || pointer[ c ].Length == 1){
      sprintf( EStr, "String %3d\xff", c );
      pointer[ c ].Length = strlen( EStr );
    }
    //
    pointer[ c ].pointer  = txt.pntr - 0x10;
    _free( pointer[ c ].Buffer );
    pointer[ c ].Buffer   = (BYTE *)malloc( pointer[ c ].Length );
    if ( !pointer[ c ].Buffer ){
      ShowMessage( "Fatal Error: Could not acquire needed memory. Closing..." );
      _free( pointer );
      Close( );
      return;
    }
    // Able to get memory
    memcpy( pointer[ c ].Buffer, EStr, pointer[ c ].Length );
    EStr[0] = 0;
  } // NEXT c

  //----------------------------//
  // Check and fix all pointers //
  // assign duplicates          //
  //----------------------------//
  for ( int c = 0; c < ptrBox->Items->Count; c++ )
  { //
    for ( int i = 0; i < c; i++ ){
      if ( pointer[ c ].pointer == pointer[ i ].pointer ){
        // Save the duplicate pointer as a
        // pointer to the index in the list
        pointer[ c ].pointer = i;
        pointer[ c ].Length  = 0;
        _free( pointer[ c ].Buffer );
        break;
      }
    }
  }

  //----------------------------------//
  // Align pointers according to data //
  // to be stored                     //
  //----------------------------------//
  // Starting pointer value
  count     = pointer[ 0 ].pointer;
  text_size = 0;
  for ( int c = 0; c < ptrBox->Items->Count; c++ )
  { //
    if ( (pointer[ c ].pointer & 0x8000) )
    { //
      pointer[ c ].pointer = count;
      // Adjust the pointer
      count     += pointer[ c ].Length;
      text_size += pointer[ c ].Length;
    }
  }

  //----------------------------------//
  // Test to see if the data is small //
  // enough to store in the ROM       //
  //----------------------------------//
  if ( text_size <= ( lpTxtMaxPos[ txt.posi ] - lpPointSize[ txt.posi ] ) )
  { // Store all the text first,
    // Then replace all the pointers
    cur_posi = lpPointSize[ txt.posi ];
    //
    for ( int c = 0; c < ptrBox->Items->Count; c++ )
    { // Is it a valid pointer or a duplicate?
      if ( (pointer[ c ].pointer & 0x8000) )
      { // write the text
        memcpy( &rom.data[ cur_posi ],
                pointer[ c ].Buffer,
                pointer[ c ].Length
              );
        //
        cur_posi += pointer[ c ].Length;
        //------------ POINTER ------------
        ptr_posi  = (pointer[ c ].Position << 1) + lpTxtBlocks[ txt.posi ];
        *(WORD *)&rom.data[ ptr_posi ] = pointer[ c ].pointer;
        //
        rom.Modified = true;
      }
      else
      { //------------ POINTER ------------
        ptr_posi  = (pointer[ c ].Position << 1) + lpTxtBlocks[ txt.posi ];
        *(WORD *)&rom.data[ ptr_posi ] = pointer[ pointer[c].pointer ].pointer;
        rom.Modified = true;
      } // END IF
    }
    //
    ShowMessage( "All text was inserted successfully!" );
  }
  else
    ShowMessage( "ERROR: Text to insert larger than space supplied!\n"
                 "Space difference: " + IntToStr( text_size - (lpTxtMaxPos[ txt.posi ] - lpPointSize[ txt.posi ]) ) + " BYTES."
               );
  //
  // Free all data and return
  txt = temp;
  //
  for ( int c = 0; c < ptrBox->Items->Count; c++ )
     _free( pointer[c].Buffer );
  //
  _free( pointer );
  //
}


//-------------------------------//
//                               //
//-------------------------------//
long __fastcall TmyForm::Text2Raw( int index )
{
  #define LINE_BREAK 0xFC
  #define TEXT_BREAK 0xFF
  #define STRING_END 0x00

  long valu,
       c_test,
       pos;
  WORD inPosi = 0,
       strLength;
  char buf[256],
       tuf[256];
  char conv[16],
       flag,
       *p1,
       *p2;

  //-------------------//
  //                   //
  //-------------------//
  sprintf( buf, ".STRING %d", index );
  //
  Find1->FindText  = AnsiString( buf );
  Find1Find( (TObject *)1 );
  //------------------------------//
  // Build translated text string //
  //------------------------------//
//  CheckMSG( );
  if ( indexLine != -1 )
  { // Clear the buffer
    // copy text to temp buffer
    TxtForm->Memo1->Clear( );
    valu = 1;  // skip ".STRING x" text
    //
    while( Trim( TxtForm->TDMemo->Lines->Strings[ indexLine + valu ] ) != ".ENDS" )
      TxtForm->Memo1->Lines->Add( TxtForm->TDMemo->Lines->Strings[ indexLine + valu++ ] );
    //
    // Don't want the ".ENDS" text
//    TxtForm->Memo1->Lines->Add( TxtForm->TDMemo->Lines->Strings[ indexLine + valu ] );

    // Add the compression
    Compress( TxtForm->Memo1 );
    //
    memset( EStr, 0, sizeof( EStr ) );
    inPosi = 0;
    //---------------------------//
    //                           //
    //---------------------------//
    for ( int i = 0; i < TxtForm->Memo1->Lines->Count; i++ )
    { //
      strcpy( buf, TxtForm->Memo1->Lines->Strings[ i ].c_str( ) );
      strLength = strlen( buf );
      // Conversion Loop
      for ( int c = 0; c < strLength; c++ )
      { //-------------------------//
        // Check for control codes //
        //-------------------------//
        c_test = 0;
        flag   = 0;
        //
        while( c_test < 256 )
        { // Do some comparisons
          memset( tuf, 0, 256 );
          pos = -1;
          while( ++pos < codes[ c_test ].length ){
            if ( codes[ c_test ].text[ pos ] < 0x7F && codes[ c_test ].text[ pos ] > 0x1F )
              tuf[ pos ] = codes[ c_test ].text[ pos ];
            else {
              tuf[ pos ] = 0;
              break;
            }
          }

          //
          if ( pos && !strncmpi( &buf[c], tuf, strlen( tuf ))
             )
          { //
            EStr[ inPosi++ ] = c_test;
            // Advance Testing DAta's curent position
            c += strlen( tuf ) - 1;
            // If this is true, do NOT set the flag!
            if ( buf[ c ] == '$' ) break;
            // We found what we need! No more test
            flag = 1;
            // Decrementc since it's part of a FOR loop
            break;
          } // END IF
          //
          c_test++;
        }

        // If FLAG still zero, no code match was found!
        if ( !flag )
        { // Check for HEX Only codes
          if ( buf[c] == '[' && buf[c + 1] == '$')
          { //
            c += 2;
            while( buf[c] != ']' ){
              memcpy( conv, &buf[c], 2 ); conv[ 2 ] = 0;
              EStr[ inPosi++ ] = strtol( conv, NULL, 16 );
              c += 2;
            }
            //
            EStr[ inPosi ] = STRING_END;
          }
          else
          { // If it comes here then it's regular data
            //
            int  t;
            for ( t = 0; t < 256; t++ ){
              if ( table.tbl[ t ] && table.tbl[ t ][0] == buf[ c ] ){
                EStr[ inPosi++ ] = t;
                break;
              }
            }
            //
            if ( t >= 256 )
              EStr[ inPosi++ ] = buf[ c ];
            //
            EStr[ inPosi   ] = STRING_END;
          }
        } // END IF

      } // END IF - Control Codes
      // Add the Line Break if needed
      EStr[ inPosi++ ] = LINE_BREAK;
      EStr[ inPosi   ] = STRING_END;
    } // NEXT i

    // Add teh End of text data
    EStr[ inPosi++ ] = TEXT_BREAK;
    EStr[ inPosi   ] = STRING_END;
  }// END IF

  return inPosi;
}


//--------------------------------//
//                                //
//--------------------------------//
void __fastcall TmyForm::TableLoader( char *tblFile )
{
  char *tval;
  long val;
  char buf[0x100],
       tuf[256],
       *p,
       *d,
       c;
  FILE *tf;

  // Clear all tabl buffers
  tf = fopen( tblFile, "rt" );
  if ( !tf ){
    ShowMessage("Could not load the table file...");
    return;
  }// END IF

  _freeTBL( );

  //-----------------------//
  // Load the table file   //
  //-----------------------//
  while( fgets( buf, 255, tf ) )
  { // Clear line break characters
    if ( strchr( buf, '\n' ) ) buf[ strlen( buf ) - 1 ] = 0;

    // Regular table values
    if ( buf[2] == '=' )
    { //
      buf[2]         = 0;
      val            = strtoul( buf, NULL, 16 );
      //--------------------------//
      // Select the buffer to use //
      //--------------------------//      
      if ( strlen( &buf[3] ) >= 2 )
      {
        table.dte[val] = (BYTE *)malloc( strlen( &buf[3] ) + 1 );
        //
        if ( !table.dte[val] )
        { //
          ShowMessage( "Error Allocating Memory for the Table File..." );
          _freeTBL( );
          return;
        }
        // copy the string
        strcpy( table.dte[val], &buf[3] );
      }
      else
      {
        table.tbl[val] = (BYTE *)malloc( strlen( &buf[3] ) + 1 );;
        //
        if ( !table.tbl[val] )
        { //
          ShowMessage( "Error Allocating Memory for the Table File..." );
          _freeTBL( );
          return;
        }
        // copy the string
        strcpy( table.tbl[val], &buf[3] );
      }
      //
      continue;
    }

    //
		 if ( buf[4] == '=' )
    { // Double table values //
      buf[4]         = 0;
      val            = strtoul( buf, NULL, 16 ) & 0x00FF;
      table.dbl[val] = (BYTE *)malloc( strlen( &buf[5] ) + 1 );
      //
      if ( !table.dbl[val] )
      { //
        ShowMessage("Error Allocating Memory for the Table File...");
        _freeTBL( );
        return;
      }
      // copy the string
      memset( table.dbl[val], 0, strlen( &buf[5] ) );
      strcpy( table.dbl[val], &buf[5] );
    } // END IF - dbl
  }// WEND

  fclose( tf );
}// END IF


//--------------------------------//
//                                //
//--------------------------------//
void __fastcall TmyForm::LoadTableFile1Click(TObject *Sender)
{
  Open1->Title      = "Open TABLE File";
  Open1->Filter     = "Table File | *.tbl";
  Open1->InitialDir = cur_dir;
  //
  if ( Open1->Execute( ) )
  { //
    strcpy( tblf, Open1->FileName.c_str( ) );
    //
    TableLoader( tblf );
  }
}

//--------------------------------//
//                                //
//--------------------------------//
void __fastcall TmyForm::Compress(TObject *Sender)
{
  TRichEdit *myMemo = (TRichEdit *)Sender;

  // Add DICTIONARY compression
  for ( int  i = 0; i < 256; i++ )
  { //
    if ( table.dbl[ i ] )
    {
      StartPos = 0;
      ToEnd    = myMemo->Text.Length( ) - StartPos;
      FoundAt  = myMemo->FindText( AnsiString( table.dbl[i] ), StartPos, ToEnd, TSearchTypes( ) << stMatchCase );
      //
      if ( FoundAt != -1 )
      { // Replace with my data
        myMemo->SelStart  = FoundAt;
        myMemo->SelLength = AnsiString( table.dbl[i] ).Length( );
        myMemo->SelText   = "[$" + IntToHex( (0x0A000 + i), 4 ) + "]";
        //
        i--;
      }
    }
  }

  // Add DTE compression
  for ( int  i = 0; i < 256; i++ )
  { //
    if ( table.dte[ i ] )
    {
      StartPos = 0;
      ToEnd    = myMemo->Text.Length( ) - StartPos;
      FoundAt  = myMemo->FindText( AnsiString( table.dte[i] ), StartPos, ToEnd, TSearchTypes( ) << stMatchCase );
      //
      if ( FoundAt != -1 )
      { // Replace with my data
        myMemo->SelStart  = FoundAt;
        myMemo->SelLength = AnsiString( table.dte[i] ).Length( );
        myMemo->SelText   = "[$" + IntToHex( i, 2 ) + "]";
        //
        i--;
      }
    }
  }
}


//--------------------------------//
//                                //
//--------------------------------//
void __fastcall TmyForm::InsertCOMPRESSIONintROM1Click(TObject *Sender)
{
  WORD POINTERS[256];
  LONG cur_posi;
  char *buf;

  if ( !rom.data || !ram ) return;
  // This game requires a table file
  if ( !tblf[0] )
  { //
    ShowMessage( "Error: Must load a table file first!" );
    return;
  }

  //------------------------//
  // DTE compression        //
  //------------------------//
  for ( int  i = 0; i < (0xB1 - 0x80); i++ )
  { //
    if ( table.dte[ i + 0x80 ] )
    {
      buf = Text2Tbl( table.dte[ i + 0x80 ], 2 );
      //
      memcpy( &rom.data[ 0x79F98 + (i << 1) ], buf, 2 );
      memcpy( &rom.data[ 0x69684 + (i << 1) ], buf, 2 );
    }
    else
    {
      rom.data[ 0x79F98 + (i << 1) ] = (0x80 + i) >> 4;
      rom.data[ 0x79F99 + (i << 1) ] = (0x80 + i) >> 0;
      //
      rom.data[ 0x69684 + (i << 1) ] = (0x80 + i) >> 4;
      rom.data[ 0x69685 + (i << 1) ] = (0x80 + i) >> 0;
    }
  }

  //------------------------//
  // Dictionary compression //
  //------------------------//
  cur_posi = 0;
  for ( int  i = 0; i < 256; i++ )
  { //
    if ( table.dbl[ i ] )
    {
      POINTERS[ i ] = (cur_posi + 0xA200);
      buf          = Text2Tbl( table.dbl[ i ], strlen( table.dbl[ i ] ) );
      memcpy( &rom.data[ 0x6E210 + cur_posi ], buf, strlen( buf ) );
      cur_posi    += strlen( buf );
      //
      rom.data[ 0x6E210 + cur_posi ] = 0xFF;
      cur_posi++;
    }
    else
    {
      POINTERS[ i ] = (cur_posi + 0xA200);
      buf = "\x7F\x7F\x7F\x7F\x7F\x7F\x7F\xFF";
      memcpy( &rom.data[ 0x6E210 + cur_posi ], buf, strlen( buf ) );
      cur_posi    += strlen( buf );
    }
  }

  // Store the pointers
  memcpy( &rom.data[ 0x6E010 ], POINTERS, 512 );
  //
  ShowMessage( "Compression inserted successfully!" );
  rom.Modified = true;
}


//-------------------------//
// IPS Patcher             //
//-------------------------//
void __fastcall TmyForm::PATCHRomFile1Click(TObject *Sender)
{
  char buf[260];
  FILE *tf,
       *f1;
  int  xx,
       k;

  if ( !rom.data || !ram ) return;
  //----------------------//
  // Patch the ROM file   //
  //----------------------//
  if ( rom.Modified )
  {
    k = Application->MessageBox( "Rom has been modified. Save these changes?",
                                 " IPS Patcher...", MB_YESNO + MB_ICONQUESTION);
    if ( k == ID_YES )
      SaveRomFile1Click( NULL );
    //  
  }
  //
  memset( &ips, 0, sizeof(TPAT) );

  Open1->Title      = "Select PATCH file(s)...";
  Open1->InitialDir = cur_dir;
  Open1->FileName   = "";
  Open1->Filter     = "IPS files (*.ips)|*.ips";
  Open1->Options    = Open1->Options << ofAllowMultiSelect;

  if ( Open1->Execute( ) )
  { //
    for ( int i = 0; i < Open1->Files->Count; i++ )
    {
      strcpy( ips.fil, Open1->Files->Strings[ i ].c_str( ) );
      tf = fopen( ips.fil, "rb" );
      _Error1:
      if ( !tf )
      { // make sure this is not pen
        ShowMessage( "File not found or is invalid. No patching performed.");
        Open1->Options = Open1->Options >> ofAllowMultiSelect;
        return;
      }
      //
      fclose( tf );

      //---------------------//
      //                     //
      //---------------------//
      // Start patching file
      tf = fopen( ips.fil, "rb" );
      f1 = fopen( "__temp__.qqq", "wb" );

      if ( !f1 || !tf ) goto _Error1;

      // Store current ROM data to the temp file
      fwrite( rom.data, 1, rom.Length, f1 );
      fclose( f1 );
      f1 = fopen( "__temp__.qqq", "r+b" );
      // Test file again
      if ( !f1 || !tf ) goto _Error1;

      ips.ofs = 0;
      ips.lof = FileSize( tf );         // get file length
      memset( buf, 0, 255 );
      fread( buf, 1, 5, tf );          // check for PATCH name tag
      // Validation check
      if ( strncmp( buf, "PATCH", 5 ) )
      { //
        fclose( tf );
        fclose( f1 ); //remove("__temp__.qqq");
        ShowMessage( "Not a valid \"PATCH\" file!" );
        Open1->Options = Open1->Options >> ofAllowMultiSelect;
        return;
      }// END IF

      //-------------------------//
      // Loop through the data   //
      //-------------------------//
      while( ftell( tf ) < ips.lof )
      { // get offset of data in ROM
        ips.ofs   = fgetc(tf);
        ips.ofs <<=16;
        ips.ofs  += ((WORD)fgetc(tf)<<8) + fgetc(tf);
        // check for EOF
        if ( ips.ofs == 0x454F46 ) break;

        // get size of data
        ips.sze = ((WORD)fgetc(tf)<<8) + fgetc(tf);

        // Check for RLE data
        if ( !ips.sze )
        { // we have RLE
          ips.sze = (WORD)(fgetc(tf)<<8) + fgetc(tf);  // get RLE size
          ips.dat = fgetc(tf);   // get RLE byte
          fseek(f1, ips.ofs, SEEK_SET);
          // Store the data
          while( ips.sze-- ) fputc( ips.dat, f1 );
        }
        else
        { // Regular data
          fseek(f1, ips.ofs, SEEK_SET);
          while( ips.sze-- ){
            xx = fgetc( tf );
            fputc( xx, f1 );
          }// WEND
        }// END IF

      }// WEND

      fclose( tf );
      rom.Length  = FileSize(f1);
      // free up current ROM data
      _free( rom.data );
      //
      rom.data = (char *)malloc( rom.Length );
      if ( !rom.data )
      { //
        fclose( f1 );
        remove("__temp__.qqq");
        Application->MessageBox( "Fatal Error: Could Not Allocate Memory for PATCHED File.\n"
                                 "Pogram will be shutdown.",
                                 "IPS Error",
                                 MB_OK + MB_ICONERROR
                               );
        //
        Close( );
        Open1->Options = Open1->Options >> ofAllowMultiSelect;
        return;
      }

      // Reload new rom data
      fseek( f1, 0, SEEK_SET );
      fread( rom.data, 1, rom.Length, f1 );
      fclose( f1 );
      remove( "__temp__.qqq" );
    }// NEXT - i

    //
    ShowMessage( "Patching is complete! Remember to SAVE the changes!" );
    rom.Modified   = true;
    Open1->Options = Open1->Options >> ofAllowMultiSelect;
    return;
  } // END IF
}


//-------------------------------//
//                               //
//-------------------------------//
void __fastcall TmyForm::DumpKanatoafile1Click(TObject *Sender)
{
  WORD pntr;
  BYTE *TxtBuf;
  FILE *tf;

  if ( !rom.data ) return;
    
  FSave->InitialDir = cur_dir;
  FSave->Title      = "Dump Working RAM to file...";
  FSave->FileName   = "";
  //
  if ( FSave->Execute( ) )
  { //
    tf = fopen( FSave->FileName.c_str( ), "wt" );
    if ( !tf ){
      ShowMessage( "Error: Could not open file for saving..." );
      return;
    }

    // Save the current lines first
    TxtForm->Memo1->Text = KanaForm->kanaEdit->Text;
    // Hide the text
    KanaForm->kanaEdit->Visible = false;

    //
    for ( int i = 0; i < cmForm->pList->Items->Count; i++ )
    { //
      pntr    = lpTxtPoints[ i ] + 0x10;
      // Check for valid pointer
      if ( (pntr & 0x3FFF) >= (lpPointSize[ txt.posi ] & 0x3FFF) )
        if ( (lpTxtBlocks[ txt.posi ] & 0x4000) )
          TxtBuf = &rom.data[ ((txt.ptr_posi & 0xFFC000) | (pntr & 0x7FFF)) ];
        else
        if ( (lpTxtBlocks[ txt.posi ] & 0x8000) )
          TxtBuf = &rom.data[ ((txt.ptr_posi & 0xFF8000) | (pntr & 0x7FFF)) ];
        else
          TxtBuf = &rom.data[ ((txt.ptr_posi & 0xFF0000) | (pntr & 0x7FFF)) ];
      else {
        fprintf( tf, ".STRING %d\n", i );
        fprintf( tf, "NON-VALID POINTER - $%04X\n", pntr - 0x10 );
        fprintf( tf, ".ENDS\n\n" );
        continue;
      }

      //
      KanaForm->ShowText( TxtBuf, 0 );
      fprintf( tf, ".STRING %d\n", i );
      for ( int c = 0; c < KanaForm->kanaEdit->Lines->Count; c++ )
        fprintf( tf, "%s\n", KanaForm->kanaEdit->Lines->Strings[ c ].c_str( ) );
      //
      fprintf( tf, ".ENDS\n\n" );
    }

    // Restore the current lines
    KanaForm->kanaEdit->Text = TxtForm->Memo1->Text;
    // Show the form again
    KanaForm->kanaEdit->Visible = true;
    //
    fclose( tf );
    ShowMessage( "Text Data dumped to the file!" );
  }
}


//-------------------------------//
//                               //
//-------------------------------//
void __fastcall TmyForm::ViewKanaDump1Click(TObject *Sender)
{
  WORD pntr;
  BYTE *TxtBuf;
  char buf[256];

  if ( !rom.data ) return;

  viewKana->Show( );
  viewKana->kanaMemo->Visible = false;

  // Save the current lines first
  TxtForm->Memo1->Text = KanaForm->kanaEdit->Text;
  // Hide the text
  KanaForm->kanaEdit->Visible = false;
  viewKana->kanaMemo->Clear( );

  //
  for ( int i = 0; i < cmForm->pList->Items->Count; i++ )
  { //
    pntr    = lpTxtPoints[ i ] + 0x10;
    // Check for valid pointer
    if ( (pntr & 0x3FFF) >= (lpPointSize[ txt.posi ] & 0x3FFF) )
      if ( (lpTxtBlocks[ txt.posi ] & 0x4000) )
        TxtBuf = &rom.data[ ((txt.ptr_posi & 0xFFC000) | (pntr & 0x7FFF)) ];
      else
      if ( (lpTxtBlocks[ txt.posi ] & 0x8000) )
        TxtBuf = &rom.data[ ((txt.ptr_posi & 0xFF8000) | (pntr & 0x7FFF)) ];
      else
        TxtBuf = &rom.data[ ((txt.ptr_posi & 0xFF0000) | (pntr & 0x7FFF)) ];
    else {
      viewKana->kanaMemo->Lines->Add( ".STRING " + AnsiString( i ) );
      viewKana->kanaMemo->Lines->Add( "NON-VALID POINTER - $" + IntToHex( pntr - 0x10, 4 ) );
      viewKana->kanaMemo->Lines->Add( ".ENDS" );
      viewKana->kanaMemo->Lines->Add( "\r\n\r\n" );
      continue;
    }

    //
    KanaForm->ShowText( TxtBuf, 0 );
    viewKana->kanaMemo->Lines->Add( ".STRING " + AnsiString( i ) );
//    viewKana->kanaMemo->Lines->Add( "\r\n" );
    //
    for ( int c = 0; c < KanaForm->kanaEdit->Lines->Count; c++ )
      viewKana->kanaMemo->Lines->Add( KanaForm->kanaEdit->Lines->Strings[ c ] );
    //
    viewKana->kanaMemo->Lines->Add( ".ENDS" );
    viewKana->kanaMemo->Lines->Add( "\r\n\r\n" );
  }

  // Restore the current lines
  KanaForm->kanaEdit->Text = TxtForm->Memo1->Text;
  // Show the form again
  KanaForm->kanaEdit->Visible = true;
  viewKana->kanaMemo->Visible    = true;
}


